package com;

import com.classes.*;

import java.io.BufferedReader;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;

/**
 * Created by mporcino on 6/13/14.
 */
public class Application {

    public static Library library;
    public static List<Item> itemsList;
    public static Map<Item, User> checkedOut;
    public static ArrayList<User> users;

    public static void main(String[] args) {

        itemsList = new ArrayList<Item>();
        itemsList.add(new Book("Design Patterns", 111111111));
        itemsList.add(new Book("Code Complete", 222222222));
        itemsList.add(new Book("The Pragmatic Programmer", 333333333));
        itemsList.add(new Movie("Titanic", "Iceberg!"));
        itemsList.add(new Movie("Moulin Rouge", "Lots of singing and dancing"));

        checkedOut = new HashMap<Item, User>();

        users = new ArrayList<User>();
        users.add(new User("111-2222", "teste"));

        library = new Library(itemsList, checkedOut);

        System.out.println("=== Welcome! ===");

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        Application.MainMenu(reader);
    }

    private static void MainMenu(BufferedReader reader)
    {
        System.out.println("Main Menu (type and confirm action number):");
        System.out.println("1: List Books");
        System.out.println("2: Book Details");
        System.out.println("3: Checkout Book");
        System.out.println("4: Return Book");
        System.out.println("5: List Movies");
        System.out.println("6: Checkout Movies");
        System.out.println("7: Return Movie");
        System.out.println("8: Quit");

        switch (SafeParseInt(readUserInput("Type in action number: ", reader)))
        {
            case 1:
                ListBooks(reader);
                break;
            case 2:
                BookDetails(reader);
                break;
            case 3:
                Checkout(reader);
                break;
            case 4:
                Return(reader);
                break;
            case 5:
                ListMovies(reader);
                break;
            case 6:
                Checkout(reader);
                break;
            case 7:
                Return(reader);
                break;
            case 8:
                Quit();
                break;
            default:
                InvalidOption(reader);
        }
    }

    private static void ListBooks(BufferedReader reader) {
        System.out.println("===== Listing Books =====");
        library.ListBooks();
        System.out.println("===== ------------- =====");

        ReturnToMenu(reader);
    }

    private static void ListMovies(BufferedReader reader) {
        System.out.println("===== Listing Movies =====");
        library.ListMovies();
        System.out.println("===== -------------- =====");

        ReturnToMenu(reader);
    }

    private static void BookDetails(BufferedReader reader) {

        int id = SafeParseInt(readUserInput("Type in Item id: ", reader));
        library.Details(id);

        ReturnToMenu(reader);
    }

    private static void Checkout(BufferedReader reader) {

        int id = SafeParseInt(readUserInput("Type in Item id: ", reader));

        User user = GetUserCredentials(reader);

        if (Authentication.Identify(user, users))
        {
            library.Checkout(id, user);
            ReturnToMenu(reader);
        }

        System.out.println("User authentication failed.");

        ReturnToMenu(reader);
    }

    private static void Return(BufferedReader reader) {

        int id = SafeParseInt(readUserInput("Type in Item id: ", reader));

        User user = GetUserCredentials(reader);

        if (Authentication.Identify(user, users))
        {
            library.Return(id);
            ReturnToMenu(reader);
        }

        System.out.println("User authentication failed.");

        ReturnToMenu(reader);
    }

    private static void Quit() {
        System.out.println("===== Thank You =====");
        return;
    }

    private static void InvalidOption(BufferedReader reader) {
        System.out.println("===== Invalid option =====");
        ReturnToMenu(reader);
    }

    private static void ReturnToMenu(BufferedReader reader)
    {
        PromptContinue(reader);
        Application.MainMenu(reader);
    }

    private static String readUserInput(String message, BufferedReader reader)
    {
        String input = "";

        if (message != null && message != "")
        {
            System.out.println(message);
        }

        try {
            input = reader.readLine();
        }
        catch (Exception e) {
            System.out.println("An error has occurred, please contact system administrator. Details: " + e.getMessage());
        }

        return input;
    }

    private static int SafeParseInt(String input)
    {
        input = input.replaceAll("\\D+","");

        if (input.isEmpty())
        {
            return 0;
        }

        return Integer.parseInt(input);
    }

    private static void PromptContinue(BufferedReader reader)
    {
        readUserInput("Press \"Enter\" to continue.", reader);
    }

    private static User GetUserCredentials(BufferedReader reader)
    {
        String libraryNumber = readUserInput("Type in User library number: ", reader);
        String password = readUserInput("Type in User password: ", reader);

        return new User(libraryNumber, password);
    }

}
